#
# $Id$
#

# CXXOPT=-O9 -DNDEBUG
CXXOPT = $(DEBUG)

########################################################################
# NO CONFIGURABLE PARTS BELOW
########################################################################

RANLIB = ranlib
CREATELIB = ar cr $(CPP_LIB) $(OBJECTS)

include def.platform
include def.compiler
include def.includes

BASE_DIR        = ..
SRC_DIR         = ${BASE_DIR}/src
TEST_DIR        = ${BASE_DIR}/testing
INCLUDE_DIR     = ${BASE_DIR}/include
INCLUDE_CPP_LIB = ${INCLUDE_DIR}/cpp-lib
OBJ_DIR         = ${BASE_DIR}/build
OBJ_SUBDIRS     = ${BASE_DIR}/build/sys             \
                  ${BASE_DIR}/build/posix           \
                  ${BASE_DIR}/build/posix1b
BIN_DIR         = ${BASE_DIR}/bin
CPP_LIB         = $(OBJ_DIR)/libcpp-lib.$(LIB_EXTENSION)

all: directories $(CPP_LIB)

INCLUDES = 					\
	-I$(INCLUDE_DIR) 			\
	-I$(BOOST_INCLUDES)

OBJECTS =					        \
	$(OBJ_DIR)/sys/file.$(OBJ_EXTENSION)	        \
	$(OBJ_DIR)/sys/util.$(OBJ_EXTENSION)	        \
	$(OBJ_DIR)/blowfish.$(OBJ_EXTENSION)	        \
	$(OBJ_DIR)/command_line.$(OBJ_EXTENSION)	\
	$(OBJ_DIR)/geometry.$(OBJ_EXTENSION)	        \
	$(OBJ_DIR)/interpolation.$(OBJ_EXTENSION)	\
	$(OBJ_DIR)/math-util.$(OBJ_EXTENSION)	        \
	$(OBJ_DIR)/matrix-io.$(OBJ_EXTENSION)	       	\
	$(OBJ_DIR)/network.$(OBJ_EXTENSION)	       	\
	$(OBJ_DIR)/registry.$(OBJ_EXTENSION)	        \
	$(OBJ_DIR)/util.$(OBJ_EXTENSION)		\
	$(OBJ_DIR)/varlist.$(OBJ_EXTENSION)

# Windoze specific parts.
WINDOWS_OBJECTS =											\
	$(OBJ_DIR)/windows/serial.$(OBJ_EXTENSION)			\
	$(OBJ_DIR)/windows/thread.$(OBJ_EXTENSION)			\
	$(OBJ_DIR)/windows/realtime.$(OBJ_EXTENSION)			\
	$(OBJ_DIR)/windows/wrappers.$(OBJ_EXTENSION)			\
	$(OBJ_DIR)/windows/wrappers_special.$(OBJ_EXTENSION)

# POSIX specific parts.
POSIX_OBJECTS =								\
	$(OBJ_DIR)/posix/wrappers.$(OBJ_EXTENSION)			\
	$(OBJ_DIR)/posix/realtime.$(OBJ_EXTENSION)

# POSIX.1B (realtime) specific parts.
POSIX1B_OBJECTS =							\
	$(OBJ_DIR)/posix/wrappers.$(OBJ_EXTENSION)			\
	$(OBJ_DIR)/posix1b/realtime.$(OBJ_EXTENSION)

TESTS =				                                \
	$(BIN_DIR)/blowfish-test	               		\
	$(BIN_DIR)/command_line-test	                        \
	$(BIN_DIR)/crypt_stream-test	                        \
	$(BIN_DIR)/interpolation-test		        	\
	$(BIN_DIR)/table-test		       	 		\
	$(BIN_DIR)/matrix-test	               			\
	$(BIN_DIR)/registry-test	               		\
	$(BIN_DIR)/quaternion-test	               		\
	$(BIN_DIR)/random-test	               			\
	$(BIN_DIR)/util-test		               		\
	$(BIN_DIR)/varlist-test	        			\
	$(BIN_DIR)/udp-test	                        	\
	$(BIN_DIR)/tcp-test					\
	#$(BIN_DIR)/iowait					\
	#$(BIN_DIR)/netutil     				\
	#$(BIN_DIR)/file-test					\
	#$(BIN_DIR)/sched-test

WINDOWS_TESTS =							\
	$(BIN_DIR)/serial-test

POSIX_TESTS =

POSIX1B_TESTS =


# DON't use spaces inside the parentheses.  It won't work.
ifeq ($(WINDOWS_STUFF),yes)
OBJECTS := $(OBJECTS) $(WINDOWS_OBJECTS)
TESTS   := $(TESTS)   $(WINDOWS_TESTS)
API_SYMBOL = -DWIN32
endif

ifeq ($(POSIX_STUFF),yes)
ifeq ($(POSIX1B_STUFF),yes)
OBJECTS := $(OBJECTS) $(POSIX1B_OBJECTS)
TESTS   := $(TESTS)   $(POSIX1B_TESTS)
else
OBJECTS := $(OBJECTS) $(POSIX_OBJECTS)
TESTS   := $(TESTS)   $(POSIX_TESTS)
endif
endif


ifdef DONT_KNOW_SYMLINKS
LINK = cp -r
else
LINK = ln -sf
endif


symlinks:
ifeq ($(POSIX_STUFF),yes)
ifeq ($(POSIX1B_STUFF),yes)
	( cd $(INCLUDE_CPP_LIB) ; $(LINK) posix1b platform_rt )
else
	( cd $(INCLUDE_CPP_LIB) ; $(LINK) posix   platform_rt )
endif
	( cd $(INCLUDE_CPP_LIB) ; $(LINK) posix   platform    )
endif
ifeq ($(WINDOWS_STUFF),yes)
	( cd $(INCLUDE_CPP_LIB) ; $(LINK) windows platform_rt )
	( cd $(INCLUDE_CPP_LIB) ; $(LINK) windows platform    )
endif


SOURCES = $(subst .o,.cpp,$(OBJECTS))

directories: $(OBJ_DIR) $(OBJ_SUBDIRS) $(BIN_DIR) 

$(CPP_LIB): symlinks $(OBJECTS)
	$(CREATELIB)
	$(RANLIB) $(CPP_LIB)

# Build the tests
tests: 		directories $(TESTS)

CXXFLAGS := $(CXXFLAGS) $(API_SYMBOL) $(MTFLAGS)
LDFLAGS  := $(LDFLAGS) $(MTFLAGS)

# DON't use spaces inside the parentheses.  It won't work.
ifeq ($(CXX),cl)

$(BIN_DIR)/%: $(OBJ_DIR)/%.$(OBJ_EXTENSION) $(CPP_LIB)
	$(CXX) /Fe$@ $< $(CPP_LIB) $(BOOST_LIB) $(LDFLAGS) $(WINSOCK) \
	user32.lib advapi32.lib

$(OBJ_DIR)/%.$(OBJ_EXTENSION) : $(SRC_DIR)/%.cpp
	$(CXX) -c $(CXXFLAGS) $(CXXOPT) $(INCLUDES) $< /Fo$@
$(OBJ_DIR)/%.$(OBJ_EXTENSION) : $(TEST_DIR)/%.cpp
	$(CXX) -c $(CXXFLAGS) $(CXXOPT) $(INCLUDES) $< /Fo$@

else
# Metrowerks and GNU.

$(BIN_DIR)/%: $(OBJ_DIR)/%.$(OBJ_EXTENSION) $(CPP_LIB)
	$(CXX) $< $(CPP_LIB) $(BOOST_LIB) $(LDFLAGS) \
	-o $@ $(PLATFORM_LIB) $(WINSOCK)

$(BIN_DIR)/sched-thread-test: \
	$(OBJ_DIR)/sched-thread-test.$(OBJ_EXTENSION) $(CPP_LIB)
	$(CXX) $< $(CPP_LIB) $(BOOST_LIB) $(LDFLAGS) \
	-o $@ $(PLATFORM_LIB) $(WINSOCK) $(BOOST_THREAD_LIB) \
	-lpthread

$(OBJ_DIR)/%.$(OBJ_EXTENSION) : $(SRC_DIR)/%.cpp
	$(CXX) -c $(CXXFLAGS) $(CXXOPT) $(INCLUDES) $< -o $@

$(OBJ_DIR)/%.$(OBJ_EXTENSION) : $(TEST_DIR)/%.cpp
	$(CXX) -c $(CXXFLAGS) $(CXXOPT) $(INCLUDES) $< -o $@

endif 


$(OBJ_DIR):
	mkdir -p $(OBJ_DIR)

$(BIN_DIR):
	mkdir -p $(BIN_DIR)

$(OBJ_SUBDIRS):
	mkdir -p $(OBJ_SUBDIRS)


clean:
	rm -f *.o core *.out *.obj *.exe *.pdb
	rm -f $(SRC_DIR)/*.o
	rm -f $(OBJECTS) libcpp-lib.a
	rm -rf $(OBJ_DIR)
	rm -rf $(BIN_DIR)
	rm -f $(TEST_DIR)/surface.out.*
	rm -f $(TEST_DIR)/*.crypt
	rm -f $(TEST_DIR)/*.stackdump
	rm -rf $(INCLUDE_CPP_LIB)/platform
	rm -rf $(INCLUDE_CPP_LIB)/platform_rt

distclean: clean
	rm -f def.compiler
	rm -f def.platform
	rm -f .depend

# Only works with GNU.
#.depend: depend
#depend:	
#	g++ -MM $(INCLUDES) $(SOURCES) $(TEST_DIR)/*.cpp > .depend
#
#include .depend
